<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D模型控制器</title>
    <!-- 引入Three.js库 -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
    <!-- 引入GLTF加载器 -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/loaders/GLTFLoader.js"></script>
    <!-- 引入OrbitControls控制器 -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/controls/OrbitControls.js"></script>
    <style>
        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        #canvas-container {
            width:300px;
            height: 300px;
        }
        canvas {
            display: block;
        }
        .loading-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.7);
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-family: Arial, sans-serif;
            z-index: 100;
        }
    </style>
</head>
<body>
<div id="canvas-container"></div>
<div class="loading-overlay" id="loading-overlay">
    <div>加载中...</div>
</div>

<script>
    // 从URL参数获取模型路径
    // const urlParams = new URLSearchParams(window.location.search);
    const modelUrl = 'https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf'
    // const userId = urlParams.get('userId');
    // 3D场景变量
    let scene, camera, renderer, controls, model;
    let initialRotation, initialPosition, initialScale;

    // 初始化3D场景
    function initScene() {
        // 创建场景、相机和渲染器
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xf0f0f0);

        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.z = 5;

        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.getElementById('canvas-container').appendChild(renderer.domElement);

        // 添加光源
        const ambientLight = new THREE.AmbientLight(0x404040, 2);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(5, 5, 5);
        scene.add(directionalLight);

        // 添加控制器，使用户可以旋转和缩放模型
        controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;

        // 窗口大小调整
        // window.addEventListener('resize', () => {
        //     camera.aspect = window.innerWidth / window.innerHeight;
        //     camera.updateProjectionMatrix();
        //     renderer.setSize(window.innerWidth, window.innerHeight);
        // });

        // 动画循环
        function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
        }
        animate();

        // 通知小程序初始化完成
        postMessageToMiniProgram({
            type: 'initialized',
            message: '3D模型查看器已初始化'
        });
    }

    // 加载3D模型
    function loadModel(url) {
        if (!url) {
            showError('未提供模型URL');
            return;
        }

        const loader = new THREE.GLTFLoader();

        // 显示加载进度
        loader.load(
            url,
            (gltf) => {
                // 模型加载成功
                model = gltf.scene;

                // 调整模型大小和位置
                const box = new THREE.Box3().setFromObject(model);
                const size = box.getSize(new THREE.Vector3());
                const center = box.getCenter(new THREE.Vector3());

                // 缩放模型使其适合视口
                const maxDim = Math.max(size.x, size.y, size.z);
                model.scale.multiplyScalar(1.0 / maxDim);

                // 重新定位模型到中心
                model.position.sub(center);

                // 保存初始状态
                initialRotation = model.rotation.clone();
                initialPosition = model.position.clone();
                initialScale = model.scale.clone();

                scene.add(model);

                // 隐藏加载指示器
                document.getElementById('loading-overlay').style.display = 'none';

                // 通知小程序模型已加载
                postMessageToMiniProgram({
                    type: 'modelLoaded',
                    message: '模型加载成功'
                });
            },
            (xhr) => {
                // 加载进度
                const percent = (xhr.loaded / xhr.total * 100).toFixed(0);
                document.getElementById('loading-overlay').innerHTML = `<div>加载中: ${percent}%</div>`;
            },
            (error) => {
                // 加载错误
                console.error('模型加载失败:', error);
                showError('模型加载失败: ' + error.message);

                // 通知小程序模型加载失败
                postMessageToMiniProgram({
                    type: 'modelLoadError',
                    message: '模型加载失败',
                    error: error.message
                });
            }
        );
    }

    // 显示错误信息
    function showError(message) {
        document.getElementById('loading-overlay').innerHTML = `<div style="color: red;">${message}</div>`;
    }

    // 向小程序发送消息
    function postMessageToMiniProgram(message) {
        if (window.__wxjs_environment === 'miniprogram') {
            wx.miniProgram.postMessage({
                data: message
            });
        }
    }

    // 处理来自小程序的消息
    function handleMiniProgramMessage(message) {
        console.log('收到小程序消息:', message);

        if (!model) {
            console.warn('模型尚未加载完成');
            return;
        }

        switch (message.type) {
            case 'rotateModel':
                const { axis, angle } = message.data;
                rotateModel(axis, angle * Math.PI / 180); // 角度转弧度
                break;
            case 'scaleModel':
                const { scale } = message.data;
                scaleModel(scale);
                break;
            case 'resetModel':
                resetModel();
                break;
            default:
                console.log('未知消息类型:', message.type);
        }
    }

    // 旋转模型
    function rotateModel(axis, angle) {
        if (model) {
            model.rotation[axis] += angle;
        }
    }

    // 缩放模型
    function scaleModel(scale) {
        if (model) {
            model.scale.set(
                initialScale.x * scale,
                initialScale.y * scale,
                initialScale.z * scale
            );
        }
    }

    // 重置模型
    function resetModel() {
        if (model) {
            model.rotation.copy(initialRotation);
            model.position.copy(initialPosition);
            model.scale.copy(initialScale);
        }
    }

    // 初始化场景和加载模型
    initScene();
    loadModel(modelUrl);

    // 监听来自小程序的消息
    if (window.__wxjs_environment === 'miniprogram') {
        window.addEventListener('message', (e) => {
            const message = e.data;
            handleMiniProgramMessage(message);
        });
    }
</script>
</body>
</html>